package com.hwq.plugin.sample

import com.android.build.api.transform.Format
import com.android.build.api.transform.QualifiedContent
import com.android.build.api.transform.Transform
import com.android.build.api.transform.TransformException
import com.android.build.api.transform.TransformInvocation
import com.android.build.gradle.internal.pipeline.TransformManager
import com.android.utils.FileUtils
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Opcodes;

class HwqTransform extends Transform {
    /**
     * 命名，Transform也就是一个任务，可以通过该名称找到对应的任务
     * app/Tasks/other/transformXXX
     * @return
     */
    @Override
    String getName() {
        return 'hwq'
    }

    /**
     * 获取输入的类型，不仅有这个class文件，还有jar文件、资源文件等
     * TransformManager.CONTENT_CLASS选择这个jar也会包含
     * @return
     */
    @Override
    Set<QualifiedContent.ContentType> getInputTypes() {
        return TransformManager.CONTENT_CLASS
    }

    /**
     * 对于要处理的范围，也就是处理主项目、还是子项目，还是第三方库，等等
     * 也可以自己调配：ImmutableSet.of(Scope.PROJECT, Scope.SUB_PROJECTS, Scope.EXTERNAL_LIBRARIES);
     * @return
     */
    @Override
    Set<? super QualifiedContent.Scope> getScopes() {
        return TransformManager.SCOPE_FULL_PROJECT
    }

    @Override
    boolean isIncremental() {
        return false
    }

    @Override
    void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
        def inputs = transformInvocation.inputs
        def outputProvider = transformInvocation.outputProvider
        inputs.each {
            it.jarInputs.each {
                File dest = outputProvider.getContentLocation(it.name, it.contentTypes, it.scopes, Format.JAR)
                println "Jar: ${it.file}, Dest: ${dest}"
                FileUtils.copyFile(it.file, dest)
            }
            it.directoryInputs.each {
                File dest = outputProvider.getContentLocation(it.name, it.contentTypes, it.scopes, Format.DIRECTORY)
                println "Dir: ${it.file}, Dest: ${dest}"
//                processInject(it.file, dest)
                FileUtils.copyDirectory(it.file, dest)
            }
        }
    }


    private void processInject(File src, File dest) throws IOException {
        String dir = src.absolutePath
        def allFiles = FileUtils.getAllFiles(src);
        allFiles.each { File file ->
            byte[] newClassBytes;
            if (file.absolutePath.contains('com/hwq/transformplugin')) {
                FileInputStream fis = new FileInputStream(file);
                // 插桩
                def cr = new ClassReader(fis);
                // 写出器
                def cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
                // 分析，处理结果写入cw
                cr.accept(new SampleTimeCostVisitor(Opcodes.ASM5, cw), ClassReader.EXPAND_FRAMES);
                newClassBytes = cw.toByteArray()
            } else {
                newClassBytes = new byte[(int) file.length()]
            }

            // class 文件
            def absolutePath = file.absolutePath
            // class文件的绝对地址去掉目录，得到的全类名.
            def fullClassPath = absolutePath.replace(dir, "");
            // 完成文件覆盖
            def outFile = new File(dest, fullClassPath);
            FileUtils.mkdirs(outFile.getParentFile());
            def fos = new FileOutputStream(outFile);
            fos.write(newClassBytes);
            fos.close();
        }
    }
}